package xyz.thoughtset.viewer.executor.blocks.tool;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.definition.ToolDefinition;
import org.springframework.ai.tool.metadata.ToolMetadata;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.ObjectUtils;
import xyz.thoughtset.viewer.executor.blocks.executor.BlockExecutorManager;
import xyz.thoughtset.viewer.executor.blocks.utlis.BlockArgsUtils;
import xyz.thoughtset.viewer.modules.step.entity.block.BlockBodyEle;

import java.util.Map;

@Slf4j
public record FunctionCallBlockToolCallback(ToolDefinition toolDefinition,
                                            BlockBodyEle bodyEle,
                                            BlockExecutorManager blockExecutorManager,
                                            ObjectMapper objectMapper, String funId) implements ToolCallback {


    @Override
    public ToolDefinition getToolDefinition() {
        return toolDefinition;
    }

    @Override
    public ToolMetadata getToolMetadata() {
        return ToolCallback.super.getToolMetadata();
    }

    @Override
    public String call(String toolInput) {
        return call(toolInput,null);
    }

    @SneakyThrows
    @Override
    public String call(String toolInput, ToolContext toolContext) {
        Map paramMap = objectMapper.readValue(toolInput,Map.class);
        Map contextMap = toolContext != null && toolContext.getContext() != null ? toolContext.getContext(): Map.of();
        if (!ObjectUtils.isEmpty(contextMap)){
            Map tmpMap = BlockArgsUtils.filterParams(bodyEle, contextMap);
            paramMap.putAll(tmpMap);
        }
//        Map inputMap = BlockArgsUtils.filterParams(bodyEle, paramMap);
        Object result = blockExecutorManager.execBlocks(funId,paramMap);
        log.info(objectMapper.writeValueAsString(result));
        return objectMapper.writeValueAsString(result);
    }
}
